//
//  Risac.swift
//  Risac
//
//  Created by remy on 2017/11/21.
//  Copyright © 2017年 remy. All rights reserved.
//

import UIKit
import DeviceKit
import os

public func log(_ message: Any,
                level: OSLogType = .info,
                file: String = #file,
                method: String = #function,
                line: Int = #line) {
    #if DEBUG
    let message = "[\((file as NSString).lastPathComponent)][\(line)][\(method)]: \(message)"
    if #available(iOS 14.0, *) {
        let logger = Logger()
        logger.log(level: level, "\(message)")
    } else {
        Swift.print(message)
    }
    #endif
}

public func print(_ message: Any, level: OSLogType = .info) {
    #if DEBUG
    let message = "\(message)"
    if #available(iOS 14.0, *) {
        let logger = Logger()
        logger.log(level: level, "\(message)")
    } else {
        Swift.print(message)
    }
    #endif
}

/// 命名空间
public final class RisacSpace<Base> {
    public let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}
public protocol RisacCompatible {
//    associatedtype ExtendedType
//    var sac: RisacSpace<ExtendedType> { get }
//    static var sac: RisacSpace<ExtendedType>.Type { get }
}
extension RisacCompatible {
    // 仅在协议扩展中声明泛型属性,协议本身不被识别为泛型协议
    public var sac: RisacSpace<Self> { return RisacSpace(self) }
    public static var sac: RisacSpace<Self>.Type { return RisacSpace<Self>.self }
}

struct AssociationKey {
    static var keys: [String: UnsafeRawPointer] = [:]
    static func make(_ str: String) -> UnsafeRawPointer {
        // 方式一
        if let key = keys[str] { return key }
        let key = UnsafeRawPointer(bitPattern: abs(str.hashValue))
        keys[str] = key
        return key!
    }
    static func from(_ str: String) -> UnsafeRawPointer {
        // 方式二
        if let key = keys[str] { return key }
        let key = str.data(using: .utf8)?.withUnsafeBytes { (uint8Ptr: UnsafeRawBufferPointer) -> UnsafeRawPointer in
            return uint8Ptr.load(as: UnsafeRawPointer.self)
        }
        keys[str] = key
        return key!
    }
}

public struct Device {
    public static let shared = DeviceKit.Device.current
    public static let realDevice: DeviceKit.Device = shared.realDevice
    public static let diagonal: Double = shared.diagonal
    public static let screenRatio: (width: Double, height: Double) = shared.screenRatio
    public static let systemVersion: String = UIDevice.current.systemVersion
    public static var IDFV: String? {
        return UIDevice.current.identifierForVendor?.uuidString
    }
    public static let isAllScreen: Bool = realDevice.isOneOf(DeviceKit.Device.allDevicesWithSensorHousing)
    public static let isWidth320: Bool = isSize320x568
    public static let isWidth375: Bool = isSize375x667 || isSize375x812
    public static let isWidth414: Bool = isSize414x736 || isSize414x896
    public static let isSize320x568: Bool = realDevice.isOneOf([.iPhone5, .iPhone5s, .iPhone5c, .iPhoneSE])
    public static let isSize375x667: Bool = realDevice.isOneOf([.iPhone6, .iPhone6s, .iPhone7, .iPhone8])
    public static let isSize414x736: Bool = realDevice.isOneOf([.iPhone6Plus, .iPhone6sPlus, .iPhone7Plus, .iPhone8Plus])
    public static let isSize375x812: Bool = realDevice.isOneOf([.iPhoneX, .iPhoneXS])
    public static let isSize414x896: Bool = realDevice.isOneOf([.iPhoneXR, .iPhoneXSMax])
}

public struct Size {
    /**
     状态栏
     # 普通屏: 显示statusBar时20pt,隐藏statusBar时0pt
     # 全面屏: 显示statusBar且竖屏时44pt,隐藏statusBar或横屏时0pt
     */
    public static var statusBarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height
    }
    /// 全面屏顶部不安全区域高度
    public static var unsafeAreaTopHeight: CGFloat {
        return UIApplication.screenOrientation.isPortrait ? 44.0 : 0.0
    }
    /// 顶部间隔区域
    public static var topExtraHeight: CGFloat {
        if Device.isAllScreen {
            return unsafeAreaTopHeight
        }
        return statusBarHeight
    }
    public static var topBarHeight: CGFloat = 44.0
    public static var topHeight: CGFloat {
        return topBarHeight + topExtraHeight
    }
    /// 全面屏底部不安全区域高度
    public static var unsafeAreaBottomHeight: CGFloat {
        return UIApplication.screenOrientation.isPortrait ? 34.0 : 0.0
    }
    /// 底部间隔区域
    public static var bottomExtraHeight: CGFloat {
        if Device.isAllScreen {
            return unsafeAreaBottomHeight
        }
        return 0.0
    }
    public static var tabBarHeight: CGFloat = 49.0
    public static var bottomHeight: CGFloat {
        return tabBarHeight + bottomExtraHeight
    }
    /// 物理分辨率的1px
    public static let onePixel: CGFloat = 1.0 / UIScreen.main.scale
    public static var screenWidth: CGFloat {
        return UIScreen.width
    }
    public static var screenHeight: CGFloat {
        return UIScreen.height
    }
}
